package ae.pcfc.etks.online.itworx.ehs.web.scheduler.jobs;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;

import ae.pcfc.etks.online.itworx.ehs.web.delegate.IMSDelegate;
import ae.pcfc.etks.online.itworx.ehs.web.delegate.WorkflowDelegate;
import ae.pcfc.etks.online.itworx.ehs.web.entity.Comment;
import ae.pcfc.etks.online.itworx.ehs.web.entity.OFCRequest;
import ae.pcfc.etks.online.itworx.ehs.web.enums.IMSRequestStatus;
import ae.pcfc.etks.online.itworx.ehs.web.enums.RequestAction;
import ae.pcfc.etks.online.itworx.ehs.web.enums.RequestStatus;
import ae.pcfc.etks.online.itworx.ehs.web.exception.CommunicationException;
import ae.pcfc.etks.online.itworx.ehs.web.exception.IMSException;
import ae.pcfc.etks.online.itworx.ehs.web.util.UtilCommon;

public class IMSJob {
	
	WorkflowDelegate workflowDelegate;
	IMSDelegate imsDelegate;
	private static Logger log = LoggerFactory.getLogger(IMSJob.class);
	
	public void setWorkflowDelegate(WorkflowDelegate workflowDelegate) {
		this.workflowDelegate = workflowDelegate;
	}
	
	public void setImsDelegate(IMSDelegate imsDelegate) {
		this.imsDelegate = imsDelegate;
	}
	
	public void checkIMSStatus() {
		List<RequestStatus> requestsStatus=new ArrayList<RequestStatus>();
		
		requestsStatus.add(RequestStatus.Payment_Confirmed);
		requestsStatus.add(RequestStatus.Inspection_In_Progress);
		requestsStatus.add(RequestStatus.Comments_Replied);
		List<OFCRequest> paymentConfirmedRequests = workflowDelegate.getAllRequestsByStatus(requestsStatus);
		String userName = null;
		for(OFCRequest request : paymentConfirmedRequests) {
			manipulateJobRequest(userName, request);
		}
	}

	@Transactional
	private void manipulateJobRequest(String userName, OFCRequest request) {
		IMSRequestStatus imsStatus = null;
		RequestAction action = null;
		String imsLogId = request.getImsLogId();
		try{
			imsStatus = imsDelegate.retrieveIMSStatus(imsLogId);
			if(IMSRequestStatus.CLOSED.equals(imsStatus)){
				request.setStatus(RequestStatus.Inspection_Approved);
				action = RequestAction.INSPECTION_CLOSED;
			} else if(IMSRequestStatus.IN_PROGRESS.equals(imsStatus) || IMSRequestStatus.IN_PROGRESS_2.equals(imsStatus)
				 || IMSRequestStatus.IN_PROGRESS_3.equals(imsStatus) || IMSRequestStatus.IN_PROGRESS_4.equals(imsStatus)){
				if((!IMSRequestStatus.IN_PROGRESS.getStatusName().equals(request.getImsStatus())
						&& (!IMSRequestStatus.IN_PROGRESS_2.getStatusName().equals(request.getImsStatus()))
						&& (!IMSRequestStatus.IN_PROGRESS_3.getStatusName().equals(request.getImsStatus())) 
						&& (!IMSRequestStatus.IN_PROGRESS_4.getStatusName().equals(request.getImsStatus())))){
					request.setStatus(RequestStatus.Inspection_In_Progress);
					action = RequestAction.INSPECTION_IN_PROGRESS;
				}
			} else if (IMSRequestStatus.RE_INSPECTION.equals(imsStatus)){
				List<Comment> imsComments = imsDelegate.retrieveIMSComments(imsLogId);
				List<Comment> ehsComments = request.getComments();
				boolean updated = manipulateEhsComments(ehsComments, imsComments);
				if(updated){
					action = RequestAction.REINSPECTION_REQUIRED;
					request.setComments(ehsComments);
					request.setStatus(RequestStatus.Non_Compliance_Comments_Exists);
				}
			} else {
				log.error("invalid ims request status ("+imsStatus+") for request ("+request.getId()+") with imsLogId ("+imsLogId+")");
				return;
			}
			if(action != null){
				userName = request.getOfficerId();
				workflowDelegate.manipulateIMSRequest(request, userName , true, action,imsStatus.toString(),UtilCommon.getCurrentDate());
			}
		} catch (IMSException e){
			log.error("error occurred while retrieving status/comments of request ("+request.getId()+") from userId ("+request.getOfficerId()+") and userName ("+userName+")",e);
			UtilCommon.rollbackTransaction();
		} catch(CommunicationException commExp) {
			log.error("communication error occurred while retrieving status/comments of request ("+request.getId()+") from userId ("+request.getOfficerId()+") and userName ("+userName+")",commExp);
			UtilCommon.rollbackTransaction();
		} catch (Exception e) {
			log.error("error occurred while handling request ("+request.getId()+") from userId ("+request.getOfficerId()+") and userName ("+userName+")",e);
			UtilCommon.rollbackTransaction();
		}
	}
	
	
	@Transactional(readOnly=true)
	private boolean manipulateEhsComments(List<Comment>ehsComments ,List<Comment>imsComments){
		if(ehsComments == null || ehsComments.size() == 0){
			if(imsComments != null){
				ehsComments.addAll(imsComments);
			}
			return true;
		}
		List<Comment> added = new ArrayList<Comment>();
		boolean found;
		boolean updated = false;
		for(Comment imsComment:imsComments){
			found = false;
			for(Comment ehsComment: ehsComments){
				if(imsComment.imsSameKey(ehsComment)){
					if(!ehsComment.isSameInspection(imsComment)){
						ehsComment.updateValues(imsComment);
						ehsComment.setReplied(false);
						updated = true;
					}
					found=true;
					break;
				}
			}
			if(!found){
				added.add(imsComment);
			}
		}
		if(added.size() > 0){
			ehsComments.addAll(added);
			updated = true;
		}
		return updated;
	}

}
